////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    AladdinsWishesGuts.h                                         //
//  Developer:   Phillip Sharpless                                            //
//  Create date: 05/17/2006                                                   //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class declaration for the slot gut of the        //
//               Australian Slot machine called Aladdin's Wishes              //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2006 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#if !defined(__ALADDINSWISHESGUTS_H__)
#define __ALADDINSWISHESGUTS_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "slotguts.h"
#include "getrand.h"

class AladdinsWishesGuts : public SlotGuts
{
	// Shared enums between client and server
	#include "AladdinsWishesCommon.h"

public:
	AladdinsWishesGuts();

	virtual ~AladdinsWishesGuts();

	virtual void classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line,
		uint8& rtnresult, uint8& multiplier );

	virtual void classifyScatters( SlotSpin *spin );

    virtual bool8 isValidGuts();

    virtual void getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId );

	//overridden to handle the randomization of the "free games" lamp
	virtual void loadSubGameData();

	virtual bool8 processClientData(uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData);

protected:

    virtual bool8 hasSavedGames();

	void initializePickFeatureGame(int32 numLamps);

	void setFeatureGameNumPicksAwarded(int32 nNumPicks);
	int32 getFeatureGameNumPicksAwarded() const;

	void initializeFeatureGamePickIndex();
	void incrementFeatureGamePickIndex();
	int32 getFeatureGamePickIndex() const;

	int32 getFeatureGameNumPicksRemaining() const;

	void setFeatureGameFreeGamePrizeLamp();
	int32 getFeatureGameFreeGamePrizeLamp() const;	
	bool hasFreeGameLampBeenSelected() const;

	void setFeatureGamePositionMask(int32 nMask);
	int32 getFeatureGamePositionMask() const;

	void setFeatureGamePickPosition(int32 nPick, int32 nLamp);
	int32 getFeatureGamePickPosition(int32 nPick) const;		

	void setFeatureGamePickWinType(int32 nPick, int32 nPickWinType);
	int32 getFeatureGamePickWinType(int32 nPick) const;

	void setFeatureGamePositionSelected( int32 nPosition, bool8 bSelected );
	bool8 getFeatureGamePositionSelected( int32 nPosition ) const;

	int32 getFeatureNumLampsSelected() const;

	virtual void preSpinClassifyResults( SlotSpin *spin );

	virtual void initDebugFunctionMap();

	enum
	{
		EVT_DEBUG_FUNCTION_LAMP_1 = BEGIN_SUB_MODIFY_NEXT_RESULT_FUNCTION_RANGE,
		EVT_DEBUG_FUNCTION_LAMP_2,
		EVT_DEBUG_FUNCTION_LAMP_3,
		EVT_DEBUG_FUNCTION_LAMP_4,
		EVT_DEBUG_FUNCTION_LAMP_5,

		EVT_DEBUG_FUNCTION_2X_PRIZE,
		EVT_DEBUG_FUNCTION_5X_PRIZE,
		EVT_DEBUG_FUNCTION_10X_PRIZE,
		EVT_DEBUG_FUNCTION_25X_PRIZE,
		EVT_DEBUG_FUNCTION_100X_PRIZE,
		EVT_DEBUG_FUNCTION_25S_PRIZE,
	};

	void DebugFeature_Lamp_1(SlotSpin *spin );
	void DebugFeature_Lamp_2(SlotSpin *spin );
	void DebugFeature_Lamp_3(SlotSpin *spin );
	void DebugFeature_Lamp_4(SlotSpin *spin );
	void DebugFeature_Lamp_5(SlotSpin *spin );

	void DebugFeature_Prize_2X( SlotSpin *spin );
	void DebugFeature_Prize_5X( SlotSpin *spin );
	void DebugFeature_Prize_10X( SlotSpin *spin );
	void DebugFeature_Prize_25X( SlotSpin *spin );
	void DebugFeature_Prize_100X( SlotSpin *spin );
	void DebugFeature_Prize_25S(SlotSpin *spin );

	static int g_nDebugLamp;
	static int g_nDebugPrize[MAX_POSITIONS];

private:

	// Helpful lookup arrays.
	static SpinResult m_aLineWinSpinResults[][6];
	static SpinResult m_aScatterWinSpinResults[6];

	// Inline functions to use with the arrays that also do
	// bounds checking.
	static SpinResult lookupLineWinSpinResult(uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return m_aLineWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupScatterWinSpinResult( uint8 nCount )
	{
		if ( nCount < 6 )
		{
			return m_aScatterWinSpinResults[ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	//helper functions for classifyStops
	SpinResult getLineWinResultWithPossibleSubstitution(
		uint8* stops, uint8 testIcon, bool& bSubstitution ) const;

	//helper functions for classifyScatters
	void tryForJackpot( SlotSpin* spin );

	SpinResult getScatterWinResult( 
		SlotSpin* spin, int32& scatterPositions, int direction) const;


	void evaluateScatterWin( SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions);
	void addScatterNearMiss(SlotSpin* spin, int32 scatterPositionsLTR, int32 scatterPositionsRTL);
	void evaluateFeatureTrigger( SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions);
};


#endif // !defined(__ALADDINSWISHESGUTS_H__)
